<?php
/**
 * класс предназначен для отслеживания нагрузки
 * @author Дмитрий Кузьма <kouzma.d@gmail.com>
 * @version 1.1
 */
class Pressure {
	protected static $_arrStart = array();
	protected static $_arrStop = array();

	/**
	 * Устанавливает начальное время выполнения скрипт
	 * 
	 * @param string $key - Ключ массива для идентификации  
	 */
	public static function setStart($key = 'default') {
		list($usec, $sec) = explode(" ", microtime());
		self::$_arrStart[$key] = (float)$usec + (float)$sec;
		return self::$_arrStart[$key];
	}

	/**
	 * Устанавливает конечное время выполнения скрипт
	 * 
	 * @param string $key - Ключ массива для идентификации  
	 */
	public static function setStop($key = 'default') {
		list($usec, $sec) = explode(" ", microtime());
		self::$_arrStop[$key] = (float)$usec + (float)$sec;
		return self::$_arrStop[$key];
	}

	/**
	 * Метод возвращает текущее время выполнения скрипта (разница)
	 * 
	 * @param string $key - Ключ массива для идентификации 
	 * @return integer
	 */
	public static function calculateCurrentDuration($key = 'default') {
		self::setStop($key);
		return round(@self::$_arrStop[$key] - @self::$_arrStart[$key], 4);
	}

	/**
	 * Метод возвращает время выполнения для таймеров
	 * 
	 * @return array - Время выполнения по ключам
	 */
	public static function getTimeArray($fromStart = false, $ignoreDBTimers = true) {
		if (empty(self::$_arrStart)) return array();
		/*self::$_arrStart = */asort(self::$_arrStart);
		$firstTime = current(self::$_arrStart);
		if ($ignoreDBTimers) {
			foreach (self::$_arrStart as $key => $value) if (preg_match('#^db[0-9]+$#', $key)) unset(self::$_arrStart[$key]);
			foreach (self::$_arrStop as $key => $value) if (preg_match('#^db[0-9]+$#', $key)) unset(self::$_arrStop[$key]);
		}
		
		$arrStartKeys = array_keys(self::$_arrStart); 
		$arrStopKeys = array_keys(self::$_arrStop);
		$arrDiffKeys = array_diff($arrStartKeys, $arrStopKeys);
		foreach ($arrDiffKeys as $key) {
			self::setStop($key);
		}
		$arrTime = array();
		if ($fromStart) {
			foreach ($arrStartKeys as $key) {
				$arrTime[$key] = self::$_arrStop[$key] - (self::$_arrStart[$key]);
			}
		}
		else {
			$nextKey = $arrStartKeys[0];
			for ($i = 1 ; $i < count($arrStartKeys) ; $i++) {
				$key = $arrStartKeys[$i - 1];
				$nextKey = $arrStartKeys[$i];
				$arrTime[$key] = self::$_arrStart[$nextKey] - (self::$_arrStart[$key]);
			}			
			$arrTime[$nextKey] = self::$_arrStop[$nextKey] - (self::$_arrStart[$nextKey]);
		}
		return $arrTime;
	}

	/**
	 * Метод сохраняет данные по нагрузке в БД
	 *
	 * @param string $url - URL
	 * @param string $key - Ключ для которого сохраняем статистику
	 * @return bool
	 */
	public static function saveDuration($url, $key) {
		$url = urldecode($url);
		$url = Service_Escape::escapeString($url);
		$objDB = Service_Database::instance();
		$objSession = User_Session::instance();
		$sessionId = $objSession->getSessionIdentifier();
		$userId = $objSession->getUserId();
		
		$duration = Pressure::calculateCurrentDuration($key);
		
		$memory = (!function_exists('memory_get_peak_usage')) ? '' : round(memory_get_peak_usage(true)/1024/1024, 2)/* . 'MB'*/;
		
		$stmtFields = "`pressure`.`duration`, `pressure`.`memory`, `pressure`.`url`, `pressure`.`created_at`, `pressure`.`ID_session`";
		$stmtValues = "'" . $duration . "', '" . $memory . "', '" . $url . "', '" . Service_Date::gLocalTime2BD() . "', '" . $sessionId . "'";
	  
	  if ($userId) {
	    $stmtFields .= ", `pressure`.`ID_user`";
	  	$stmtValues .= ", '" . $userId . "'";
	  }
		$stmt = "INSERT INTO `pressure`	(" . $stmtFields . ") VALUES (" . $stmtValues . ")";
		return $objDB->query($stmt);
	}
	
	/**
	 * Метод сохраняет данные посещенйи администраторов
	 *
	 * @param string $url - URL
	 * @return bool
	 */
	public static function saveSupportAdminDuration() {
		$url = Service_Escape::escapeString($_SERVER['REQUEST_URI']);
		if ($url == '/rus/ajax/support/get_nr_notice') return;
		$objDB = Service_Database::instance();
		
		$stmt = "INSERT INTO `support_pressure`(`ID_user`, `url`, `created_at`) VALUES ('" . User_User::getId() . "', '" . $url . "', '" . Service_Date::gLocalTime2BD() . "')";
		return $objDB->query($stmt);
	}

	/**
	 * Получение статистики о нагрузке страниц
	 *
	 * @param $listType - тип нагрузки
	 * @return массив с информацией о нагрузке
	 */
	public static function getPressure($listType) {
		$objDB = Service_Database::instance();
		switch ($listType) {
			case 0:
			  $stmt = "SELECT AVG(`duration`) AS duration, COUNT(`url` ) AS `amount`, `url`
				FROM `pressure`
				WHERE  `created_at` > '2012-04-23 00:00:00'
				GROUP BY `url`, `pressure_type`
				ORDER BY 1 DESC
				LIMIT 0, 101";
			  break;
			case 1:
			  $stmt = "SELECT AVG(`duration`) AS duration, COUNT(`url_small` ) AS `amount`, `url_small`
				FROM `pressure`
				WHERE `url_small` != '' AND `created_at` > '2012-04-23 00:00:00'
				GROUP BY `url_small`, `pressure_type`
				ORDER BY 1 DESC
				LIMIT 0, 101";
			  break;
			case 2:
			  $stmt = "SELECT SUM(`duration`) AS duration, COUNT(`url_small` ) AS `amount`, `url_small`
				FROM `pressure`
				WHERE `url_small` != '' AND `created_at` > '2012-04-23 00:00:00'
				GROUP BY `url_small`, `pressure_type`
				ORDER BY 1 DESC
				LIMIT 0, 101";
			  break;
			default:
			  $stmt = "SELECT AVG(`duration`) AS duration, COUNT(`url` ) AS `amount`, `url`
				FROM `pressure`
				WHERE  `created_at` > '2012-04-23 00:00:00'
				GROUP BY `url`, `pressure_type`
				ORDER BY 1 DESC
				LIMIT 0, 101";
			  break;
		}
		echo $stmt;
		return $objDB->select($stmt);
	}
}
?>